package com.youi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.youi.common.Common;
import com.youi.common.DelStatus;
import com.youi.entity.*;
import com.youi.service.*;
import com.youi.third.yibaopay.YibaopayUtil;
import com.youi.third.yibaopay.model.Divideresult;
import com.youi.util.LogUtil;
import com.youi.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 打款处理的异步服务
 */
@Service
public class AsyncTremittanceService {

    final private static Boolean SKIP_THIRD_FOR_DEBUG = false;

    private static HashMap<String, Object> params(String key, Object value) {
        HashMap<String, Object> result = new HashMap<>();
        result.put(key, value);
        return result;
    }

    private static HashMap<String, Object> paramsNODel(String key, Object value) {
        HashMap<String, Object> result = paramsNODel();
        result.put(key, value);
        return result;
    }

    private static HashMap<String, Object> paramsNODel() {
        HashMap<String, Object> result = new HashMap<>();
        result.put(Common.DELSTATUS, DelStatus.NODEL);
        return result;
    }

    @Autowired
    private MerchantwithdrawdetailService merchantwithdrawdetailService;

    @Autowired
    private MerchantwithdrawService merchantwithdrawService;

    @Autowired
    private TremittanceService tremittanceService;

    @Autowired
    private UserorderService userorderService;

    @Autowired
    private YibaopaymentService yibaopaymentService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    private OrderprofitdetailService orderprofitdetailService;

    @Autowired
    private YibaodivideService yibaodivideService;
    
    @Autowired
	private PlamtwithdrawService plamtwithdrawService;
	@Autowired
	private PlamtwithdrawdetailService plamtwithdrawdetailService;

    @Transactional
    @Async
	public void testTrancationOnly(Long merchantwithdrawdetailId){
        //获取并加锁
        LogUtil.Info("TestTrancation"+merchantwithdrawdetailId+":getForUpdate");
        Merchantwithdrawdetail merchantwithdrawdetail = merchantwithdrawdetailService.getForUpdate(
                merchantwithdrawdetailId);
        LogUtil.Info("TestTrancation"+merchantwithdrawdetailId+":data fetched");
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LogUtil.Info("TestTrancation"+merchantwithdrawdetailId+":quit");
    }


    /**
     * 对于单条merchantwithdrawdetail，异步执行分账
     * @param merchantwithdrawdetailId
     * @throws IOException
     */
    @Transactional
    @Async
    public void divideMerchantByAgree(Long merchantwithdrawdetailId) throws IOException {

//        try {
//            Thread.sleep(new Random().nextInt(5000));
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        //获取并加锁
        LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+": getForUpdate ");
        Merchantwithdrawdetail merchantwithdrawdetail = merchantwithdrawdetailService.getForUpdate(
                merchantwithdrawdetailId);
        if (merchantwithdrawdetail.getDelStatus() == DelStatus.DEL) {
            LogUtil.Info("fail: deleted " + merchantwithdrawdetailId);
            return;
        }
//          `profitStatus` int DEFAULT NULL COMMENT '分润状态(0未分账 1已分账)',
        LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+": profitStatus:"
                +merchantwithdrawdetail.getProfitStatus()+"("+merchantwithdrawdetail.getId()+")");
        if (merchantwithdrawdetail.getProfitStatus() != 0) {
            //只能处理未分账状态的数据
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail - profitStatus -" + merchantwithdrawdetail.getProfitStatus());
            return;
        }

        //检查merchantwithdraw
        Merchantwithdraw merchantwithdraw = merchantwithdrawService.getByParam(
                paramsNODel("twithdrawNo", merchantwithdrawdetail.getWithdrawNo()));
        if (merchantwithdraw == null) {
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail merchantwithdraw not exists- "+ merchantwithdrawdetail.getWithdrawNo());
            return;
        }
////        merchantwithdraw表：
////`status` int DEFAULT NULL COMMENT '状态(-1作废 0未审核 1已审核(待打款） 2已审核(延迟打款) 3提现成功 4提现失败 5延迟打款)',
//        Integer mstatus = merchantwithdraw.getStatus();
//        if (mstatus != 1) {
//            LogUtil.Info("fail: merchantwithdraw status not valid " + merchantwithdraw.getId() + " - " + mstatus);
//            return;
//        }

        //检查tremittance
        Tremittance tremittance = tremittanceService.getByParam(paramsNODel(
                "withdrawNo", merchantwithdraw.getTwithdrawNo()));
        if (tremittance == null) {
            merchantwithdrawdetail.setMerchantStatus(4);
            merchantwithdrawdetail.setProfitStatus(-1);
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail - tremittance not exists - "+merchantwithdraw.getTwithdrawNo());
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            return;
        }
//        tremittance表：
//`type` int DEFAULT NULL COMMENT '打款类型(0供应商打款 1平台打款 2团长打款)',
//  `status` int DEFAULT NULL COMMENT '审核状态(-1不同意打款 0未审核 1同意打款 2延迟打款)',
//  `payStatus` int DEFAULT NULL COMMENT '打款状态(-1失败 0处理中 1成功)',
        Integer tType = tremittance.getType();
        Integer tStatus = tremittance.getStatus();
        Integer tPayStatus = tremittance.getPayStatus();
        if (tType != 0) {
            LogUtil.Info("fail: tremittance type not valid " + tremittance.getId() + " - " + tType);
        }
        if (tStatus != 1) {
            LogUtil.Info("fail: tremittance status not valid " + tremittance.getId() + " - " + tStatus);
        }
        if (tPayStatus != 1) { //tremittance.payStatus 在这时应该都等于1
            LogUtil.Info("fail: tremittance payStatus not valid " + tremittance.getId() + " - " + tPayStatus);
        }

        /////////////////////////////////////////////////////////////////////////////////
        //状态检查完成，下面正式处理
        /////////////////////////////////////////////////////////////////////////////////

//  `merchantStatus` int DEFAULT NULL COMMENT '供应商提现状态(0不可提现 1未提现 2提现中 3提现成功 4提现失败)',

        //检查userorder
        Userorder userorder = userorderService.getByParam(paramsNODel("orderNo", merchantwithdrawdetail.getOrderNo()));
        if (userorder == null) {
            merchantwithdrawdetail.setMerchantStatus(4);
            merchantwithdrawdetail.setProfitStatus(-1);
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail -  userorder not exists "+ merchantwithdrawdetail.getOrderNo());
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            return;
        }

        //yibaopayment
        Yibaopayment yibaopayment = yibaopaymentService.getByParam(
                paramsNODel(), params("orderNos", userorder.getOrderNo()), null);
        if (yibaopayment == null) {
            merchantwithdrawdetail.setMerchantStatus(4);
            merchantwithdrawdetail.setProfitStatus(-1);
            userorder.setMerchantStatus(4);
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail - yibaopayment not exists " + userorder.getOrderNo());
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            return;
        }
        if (yibaopayment.getPaymentNo()==null) {
        	merchantwithdrawdetail.setMerchantStatus(4);
            merchantwithdrawdetail.setProfitStatus(-1);
            userorder.setMerchantStatus(4);
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail =========缺少易宝流水信息,订单号为:"+userorder.getOrderNo()+" - ");
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            return;
		}

        //merchant
        Merchant merchant = merchantService.get(userorder.getMerchantId());
        if (merchant == null) {
            merchantwithdrawdetail.setMerchantStatus(4);
            merchantwithdrawdetail.setProfitStatus(-1);
            userorder.setMerchantStatus(4);
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail - merchant not exists " + userorder.getMerchantId());
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            return;
        }

        //orderprofitdetailService
        Orderprofitdetail orderprofitdetail = orderprofitdetailService.getByParam(
                paramsNODel("orderNo", userorder.getOrderNo()));
        if (orderprofitdetail == null) {
            merchantwithdrawdetail.setMerchantStatus(4);
            merchantwithdrawdetail.setProfitStatus(-1);
            userorder.setMerchantStatus(4);
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": fail - orderprofitdetail not exists " + userorder.getOrderNo());
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            return;
        }

        if (SKIP_THIRD_FOR_DEBUG){
            merchantwithdrawdetail.setMerchantStatus(3);
            merchantwithdrawdetail.setProfitStatus(1);
            merchantwithdrawdetail.setGmtComplete(new Date());
            merchantwithdrawdetail.setGmtWithdraw(new Date());
            userorder.setMerchantStatus(3);
            userorder.setGmtMerchantWith(new Date());
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": SKIP_THIRD_FOR_DEBUG success");
            merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
            userorderService.saveOrUpdate(userorder);
        }else {
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+ ": - YibaopayUtil.yibaoDivideToMerchant start");
        	 Divideresult divideresult = YibaopayUtil.yibaoDivideToMerchant(yibaopayment.getSerialNumber(),
                     yibaopayment.getPaymentNo(), orderprofitdetail.getMerAmount(), merchant.getMerchantNo());
            LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId
                    +": - YibaopayUtil.yibaoDivideToMerchant-result:"+((divideresult!=null) ? divideresult.getCode() : "null"  ) );
             if (divideresult != null && divideresult.getCode().equals("OPR00000")) {
                Yibaodivide yibaodivide = new Yibaodivide(divideresult.getStatus(), divideresult.getOrderId(), userorder.getOrderNo(), divideresult.getUniqueOrderNo(),
                         divideresult.getDivideRequestId(), divideresult.getDivideDetail());
                 yibaodivideService.saveOrUpdate(yibaodivide);
                 merchantwithdrawdetail.setMerchantStatus(3);
                 merchantwithdrawdetail.setProfitStatus(1);
                 merchantwithdrawdetail.setGmtComplete(new Date());
                 merchantwithdrawdetail.setGmtWithdraw(new Date());
                 userorder.setMerchantStatus(3);
                 userorder.setGmtMerchantWith(new Date());
                 LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+" - success:"+merchantwithdrawdetail.getGmtComplete());
                 merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
                 userorderService.saveOrUpdate(userorder);
//             merchantwithdraw.setStatus(3);
//             merchantwithdrawService.saveOrUpdate(merchantwithdraw);
//             realityAmount+=orderprofitdetail.getMerAmount();
//             tremittance.setPayStatus(2);
             } else {
                 merchantwithdrawdetail.setMerchantStatus(4);
                 merchantwithdrawdetail.setProfitStatus(-1);
                 userorder.setMerchantStatus(4);
                 LogUtil.Info("asyncDivideMerchantByAgree"+merchantwithdrawdetailId+" - failure");
                 merchantwithdrawdetailService.saveOrUpdate(merchantwithdrawdetail);
                 userorderService.saveOrUpdate(userorder);
//             tremittance.setPayStatus(-1);
             }
        }//SKIP_THIRD_FOR_DEBUG

        ///////////////////////////////////////////////////////////////
        // 如果全部结束，则设置merchantwithdraw 和 tremittance 的标志字段
        // 目前该部分逻辑在定时器中实现，不在这里调用了
        ///////////////////////////////////////////////////////////////
    } 

    /**
     * 对于单条tremittance，判断是否其下所有的明细分账都已经完成，如果完成则修改merchantwithdraw和Tremittance的状态
     * @param tremittanceId
     * @throws IOException
     */
    @Transactional
    public void finishMerchantDivide(Long tremittanceId) throws IOException {
        //先加锁，确保每次统计完整性
        Tremittance tremittance = tremittanceService.getForUpdate(tremittanceId);
        //判断分账是否而已经完成
        List<Tremittance> finishedList = tremittanceService.listForFinishMerchantDivide(tremittanceId);
        if (finishedList.size() == 0 ){
            LogUtil.Info("fail: get finished finishMerchantDivide" + tremittanceId);
            return;
        }
        tremittance = finishedList.get(0);

        //检查merchantwithdraw
        Merchantwithdraw merchantwithdraw = merchantwithdrawService.getByParam(
                paramsNODel("twithdrawNo", tremittance.getWithdrawNo()));
        if (merchantwithdraw == null) {
            LogUtil.Info("fail: merchantwithdraw not exists " + tremittance.getWithdrawNo());
            return;
        }

        //进行统计和更新
        _finishMerchantDivide(tremittance,merchantwithdraw);
    }


    //判断单条tremittance的分账情况，如果所有明细都已经完成则更新状态
    @Transactional
    public void _finishMerchantDivide(Tremittance tremittance,Merchantwithdraw merchantwithdraw) throws IOException {

        LogUtil.Info("_finishMerchantDivide start");

        //统计
        List<Map<String, Object>> stats = tremittanceService.merchantDivideStat(tremittance.getId());

        int success = 0; //提现成功数量
        int failure = 0; // 提现失败数量
        double amount = 0.0; //提现金额总计

        for (Map<String, Object> line : stats){
            Integer status = (Integer) line.get("merchantStatus");
            Long count = (Long) line.get("statusCount");
            LogUtil.Info(line.get("merAmount").toString());
            BigDecimal merAmount = (BigDecimal) line.get("merAmount");
//`merchantStatus` int DEFAULT NULL COMMENT '供应商提现状态(0不可提现 1未提现 2提现中 3提现成功 4提现失败)',
            if (status == 3) { //提现成功
                success = count.intValue();
                amount = merAmount.doubleValue();
            }else if (status == 4) { //提现失败
                failure = count.intValue();
            }
        }

//        merchantwithdraw表：
//`status` int DEFAULT NULL COMMENT '状态(-1作废 0未审核 1已审核(待打款） 2已审核(延迟打款) 3提现成功 4提现失败 5延迟打款)',
//        tremittance表：
//  `payStatus` int DEFAULT NULL COMMENT '打款状态(-1失败 0处理中 1成功)',
//  根据要求，在成功时设置成2

        //目前是按照只要有一条成功，就算是成功的标准修改
        if (success > 0) {
            merchantwithdraw.setStatus(3);
            tremittance.setPayStatus(2); //原本代码里都设置为2，虽然数据库列注释里没有2，根据要求还是设置成2
        }else{
            merchantwithdraw.setStatus(4);
            tremittance.setPayStatus(-1);
        }
        merchantwithdrawService.saveOrUpdate(merchantwithdraw);

//        tremittance.setGmtAgree(new Date());
//        tremittance.setAgreeUserId(sysuser.getId());
        //上面两个字段之前就已经设置并且保存完成
        //这一次只保存payStatus加上下面两个字段
        tremittance.setGmtReality(new Date());
        LogUtil.Info(Double.toString(amount));
        tremittance.setRealityAmount(ObjectUtil.sciCal(amount, 2));
        tremittance.setGmtModify(new Date());
        tremittanceService.saveOrUpdate(tremittance);
    }
    
    /**
     * 对单条plamtwithdrawdetail进行异步分账
     * @throws IOException
     */
    @Transactional
    @Async
    public void dividePlatformByAgree(Long plamtwithdrawdetailId,Platmerchantno platmerchantno) throws IOException {
    	 //获取并加锁
        LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+": getForUpdate" );
    	Plamtwithdrawdetail plamtwithdrawdetail=plamtwithdrawdetailService.getForUpdate(plamtwithdrawdetailId);
    	if (plamtwithdrawdetail.getDelStatus() == DelStatus.DEL) {
            LogUtil.Info("fail: deleted " + plamtwithdrawdetail);
            return;
        }
        LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+" - status:"+plamtwithdrawdetail.getStatus()+
                "("+plamtwithdrawdetail.getId()+")");
    	if (plamtwithdrawdetail.getStatus() != 2) {
            //只能处理未分账状态的数据
            LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+"fail: merchantwithdrawdetail profitStatus not valid  - " + plamtwithdrawdetail.getStatus());
            return;
        }
    	 //检查plamtwithdraw
        Plamtwithdraw plamtwithdraw = plamtwithdrawService.getByParam(
                paramsNODel("withdrawNo", plamtwithdrawdetail.getWithdrawNo()));
        if (plamtwithdraw == null) {
            LogUtil.Info("fail: plamtwithdraw not exists " + plamtwithdrawdetail.getWithdrawNo());
            return;
        }

        Tremittance tremittance = tremittanceService.getByParam(paramsNODel(
                "withdrawNo", plamtwithdrawdetail.getWithdrawNo()));
        if (tremittance == null) {
            plamtwithdrawdetail.setStatus(4);
            plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
            LogUtil.Info("fail"+plamtwithdrawdetail.getId()+": tremittance not exists " + plamtwithdrawdetail.getWithdrawNo());
            return;
        }
        Integer tType = tremittance.getType();
        Integer tStatus = tremittance.getStatus();
        Integer tPayStatus = tremittance.getPayStatus();
        if (tType != 0) {
            LogUtil.Info("fail: tremittance type not valid " + tremittance.getId() + " - " + tType);
        }
        if (tStatus != 1) {
            LogUtil.Info("fail: tremittance status not valid " + tremittance.getId() + " - " + tStatus);
        }
        if (tPayStatus != 1) { //tremittance.payStatus 在这时应该都等于1
            LogUtil.Info("fail: tremittance payStatus not valid " + tremittance.getId() + " - " + tPayStatus);
        }
        //检查userorder
        Userorder userorder = userorderService.getByParam(paramsNODel("orderNo", plamtwithdrawdetail.getOrderNo()));
        if (userorder == null) {
            plamtwithdrawdetail.setStatus(4);
            plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
            LogUtil.Info("fail"+plamtwithdrawdetail.getId()+": userorder not exists " + plamtwithdrawdetail.getOrderNo());
            return;
        }

        //yibaopayment
        Yibaopayment yibaopayment = yibaopaymentService.getByParam(
                paramsNODel(), params("orderNos", userorder.getOrderNo()), null);
        if (yibaopayment == null) {
            plamtwithdrawdetail.setStatus(4);
            userorder.setMerchantStatus(4);
            plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
            LogUtil.Info("fail"+plamtwithdrawdetail.getId()+": yibaopayment not exists " + userorder.getOrderNo());
            return;
        }

        //merchant
        Merchant merchant = merchantService.get(userorder.getMerchantId());
        if (merchant == null) {
            plamtwithdrawdetail.setStatus(4);
            userorder.setMerchantStatus(4);
            plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
            LogUtil.Info("fail"+plamtwithdrawdetail.getId()+": merchant not exists " + userorder.getMerchantId());
            return;
        }

        //orderprofitdetailService
        Orderprofitdetail orderprofitdetail = orderprofitdetailService.getByParam(
                paramsNODel("orderNo", userorder.getOrderNo()));
        if (orderprofitdetail == null) {
            plamtwithdrawdetail.setStatus(4);
            userorder.setMerchantStatus(4);
            plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
            LogUtil.Info("fail"+plamtwithdrawdetail.getId()+": orderprofitdetail not exists " + userorder.getOrderNo());
            return;
        }

        if (SKIP_THIRD_FOR_DEBUG){
        	plamtwithdrawdetail.setStatus(3);
        	plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
        	userorder.setPlatformStatus(3);
			userorder.setGmtPlatformWith(new Date());
			userorderService.saveOrUpdate(userorder);
			plamtwithdraw.setStatus(3);
            LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+" debug success");
			plamtwithdrawService.saveOrUpdate(plamtwithdraw);

        }else {
        	Double firstAmount=0.00;
        	if (orderprofitdetail.getFirstAmount()!=null) {
				firstAmount=orderprofitdetail.getFirstAmount();
			}
        	Double secondAmount=0.00;
        	if (orderprofitdetail.getSecondAmount()!=null) {
				secondAmount=orderprofitdetail.getSecondAmount();
			}
        	Double platAmount=0.00;
        	if (orderprofitdetail.getPlatAmount()!=null) {
				platAmount=orderprofitdetail.getPlatAmount();
			}
        	Double profitAmount=ObjectUtil.sciCal(firstAmount+secondAmount+platAmount, 2);
            LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+" - YibaopayUtil.yibaoDivideToMerchant start");
        	Divideresult divideresult =YibaopayUtil.yibaoDivideToMerchant(yibaopayment.getSerialNumber(),
    				yibaopayment.getPaymentNo(),profitAmount , platmerchantno.getMerchantNo());
    				Yibaodivide yibaodivide=null;
            LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId
                    +" - YibaopayUtil.yibaoDivideToMerchant result"
                    +((divideresult!=null) ? divideresult.getCode() : "null"  ) );
    				if (divideresult!=null&&divideresult.getCode().equals("OPR00000")) {
    					yibaodivide=new Yibaodivide(divideresult.getStatus(), divideresult.getOrderId(), userorder.getOrderNo(), divideresult.getUniqueOrderNo(),
    					divideresult.getDivideRequestId(), divideresult.getDivideDetail());
    					yibaodivideService.saveOrUpdate(yibaodivide);
    					plamtwithdrawdetail.setStatus(3);
    					userorder.setPlatformStatus(3);
    					userorder.setGmtPlatformWith(new Date());
                        LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+" - success "+userorder.getGmtPlatformWith());
    					plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
    					userorderService.saveOrUpdate(userorder);
    					plamtwithdraw.setStatus(3);
    					plamtwithdrawService.saveOrUpdate(plamtwithdraw);
    				}else {
    					plamtwithdrawdetail.setStatus(4);
    					userorder.setPlatformStatus(4);
                        LogUtil.Info("asyncDividePlatformByAgree"+plamtwithdrawdetailId+" - failure ");
    					plamtwithdrawdetailService.saveOrUpdate(plamtwithdrawdetail);
    					userorderService.saveOrUpdate(userorder);
    				}
		}
    }

    /**
     *  对于单条tremittance，判断是否其下所有的明细分账都已经完成，如果完成则修改plamtwithdraw和Tremittance的状态
     * @param tremittanceId
     * @throws IOException
     */
    @Transactional
    public void finishPlatformDivide(Long tremittanceId) throws IOException {
        //先加锁，确保每次统计完整性
        Tremittance tremittance = tremittanceService.getForUpdate(tremittanceId);
        //判断分账是否而已经完成
        List<Tremittance> finishedList = tremittanceService.listForFinishPlatfotmDivide(tremittanceId);
        if (finishedList.size() == 0 ){
            LogUtil.Info("fail: get finished finishMerchantDivide" + tremittanceId);
            return;
        }
        tremittance = finishedList.get(0);

        //检查merchantwithdraw
        Plamtwithdraw plamtwithdraw = plamtwithdrawService.getByParam(
                paramsNODel("withdrawNo", tremittance.getWithdrawNo()));
        if (plamtwithdraw == null) {
            LogUtil.Info("fail: merchantwithdraw not exists " + tremittance.getWithdrawNo());
            return;
        }

        //进行统计和更新
        _finishMerchantDivide(tremittance,plamtwithdraw);
    }

    @Transactional
    public void _finishMerchantDivide(Tremittance tremittance,Plamtwithdraw plamtwithdraw) throws IOException {

        LogUtil.Info("_finishMerchantDivide start");

        //统计
        List<Map<String, Object>> stats = tremittanceService.PlatfotmDivideStat(tremittance.getId());

        int success = 0; //提现成功数量
        int failure = 0; // 提现失败数量
        double amount = 0.0; //提现金额总计

        for (Map<String, Object> line : stats){
            Integer status = (Integer) line.get("status");
            Long count = (Long) line.get("statusCount");
            LogUtil.Info(line.get("platAmount").toString());
            BigDecimal platAmount = (BigDecimal) line.get("platAmount");
            BigDecimal firstAmount = (BigDecimal) line.get("firstAmount");
            BigDecimal secondAmount = (BigDecimal) line.get("secondAmount");
//`merchantStatus` int DEFAULT NULL COMMENT '供应商提现状态(0不可提现 1未提现 2提现中 3提现成功 4提现失败)',
            if (status == 3) { //提现成功
                success = count.intValue();
                if (platAmount!=null) {
					amount+=ObjectUtil.sciCal(platAmount.doubleValue(), 2);
				}
                if (firstAmount!=null) {
					amount+=ObjectUtil.sciCal(firstAmount.doubleValue(), 2);
				}
                if (secondAmount!=null) {
					amount+=ObjectUtil.sciCal(secondAmount.doubleValue(), 2);
				}               
            }else if (status == 4) { //提现失败
                failure = count.intValue();
            }
        }

//        merchantwithdraw表：
//`status` int DEFAULT NULL COMMENT '状态(-1作废 0未审核 1已审核(待打款） 2已审核(延迟打款) 3提现成功 4提现失败 5延迟打款)',
//        tremittance表：
//  `payStatus` int DEFAULT NULL COMMENT '打款状态(-1失败 0处理中 1成功)',
//  根据要求，在成功时设置成2

        //目前是按照只要有一条成功，就算是成功的标准修改
        if (success > 0) {
            plamtwithdraw.setStatus(2);
            tremittance.setPayStatus(2); //原本代码里都设置为2，虽然数据库列注释里没有2，根据要求还是设置成2
        }else{
            plamtwithdraw.setStatus(4);
            tremittance.setPayStatus(-1);
        }
        plamtwithdrawService.saveOrUpdate(plamtwithdraw);

//        tremittance.setGmtAgree(new Date());
//        tremittance.setAgreeUserId(sysuser.getId());
        //上面两个字段之前就已经设置并且保存完成
        //这一次只保存payStatus加上下面两个字段
        tremittance.setGmtReality(new Date());
        LogUtil.Info(Double.toString(amount));
        tremittance.setRealityAmount(ObjectUtil.sciCal(amount, 2));
        tremittance.setGmtModify(new Date());
        tremittance.setServiceCharge(0.0);
        tremittanceService.saveOrUpdate(tremittance);
    }
    
    
    
    /**
     * 定时器，每隔1分钟判断一次是否有分账完成的记录可以设置标志。
     * @throws InterruptedException
     */
//    @Scheduled(cron = "0 * * * * ?")
//    public void scheduleCheckFinishMerchant() throws InterruptedException {
//        List<Tremittance> merchantFinished = tremittanceService.listForFinishMerchantDivide(null);
//        for (Tremittance tremittance : merchantFinished){
//            try {
//                finishMerchantDivide(tremittance.getId());               
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        List<Tremittance> platformFinished = tremittanceService.listForFinishPlatfotmDivide(null);
//        for (Tremittance tremittance : platformFinished) {
//        	try {
//				finishPlatformDivide(tremittance.getId());
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
//    }

}